package com.gdufe.firesafe.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gdufe.firesafe.dao.*;
import com.gdufe.firesafe.exception.RRException;
import com.gdufe.firesafe.model.entity.*;
import com.gdufe.firesafe.model.enums.DeviceTypeEnum;
import com.gdufe.firesafe.model.vo.HouseBasicInfoVO;
import com.gdufe.firesafe.model.vo.HouseStatisticsVO;
import com.gdufe.firesafe.model.vo.HouseTreeVO;
import com.gdufe.firesafe.model.vo.ResponsibleForVO;
import com.gdufe.firesafe.service.HouseService;
import com.gdufe.firesafe.service.InspectionService;
import com.gdufe.firesafe.service.OwnerService;
import com.gdufe.firesafe.utils.PageUtils;
import com.gdufe.firesafe.utils.Query;
import com.gdufe.firesafe.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service("houseService")
public class HouseServiceImpl extends ServiceImpl<HouseDao, HouseEntity> implements HouseService {

    @Autowired
    private FloorDao floorDao;
    @Autowired
    private BuildingDao buildingDao;
    @Autowired
    private OwnerService ownerService;
    @Autowired
    private InspectionDao inspectionDao;
    @Autowired
    private InspectionService inspectionService;
    @Autowired
    private InspectorDao inspectorDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<HouseEntity> page = this.page(
                new Query<HouseEntity>().getPage(params),
                new QueryWrapper<>()
        );

        return new PageUtils(page);
    }

    //获取房屋树形结构
    @Override
    public List<HouseTreeVO> getHouseTree() {
        //获取所有楼栋，楼层，房屋
        List<BuildingEntity> buildingList = buildingDao.selectList(null);
        List<FloorEntity> floorList = floorDao.selectList(null);
        List<HouseEntity> houseList = this.list();

        //组装返回结果
        List<HouseTreeVO> res = new ArrayList<>();
        for (BuildingEntity building : buildingList) {
            //遍历楼栋，新建楼栋vo，设置id和name
            HouseTreeVO buildingVO = new HouseTreeVO();
            buildingVO.setValue(building.getId());
            buildingVO.setLabel(building.getName());
            //设置children，即第二级的楼层list
            List<HouseTreeVO> floorListVO = new ArrayList<>();
            for (FloorEntity floor : floorList) {
                if (floor.getBuildingId().equals(building.getId())) {
                    //若楼层属于该楼栋，新建楼层vo，设置id和name
                    HouseTreeVO floorVO = new HouseTreeVO();
                    floorVO.setValue(floor.getId());
                    floorVO.setLabel(floor.getFloorNumber() + "层");
                    //设置children，即第三级的房屋list
                    List<HouseTreeVO> houseListVO = new ArrayList<>();
                    for (HouseEntity house : houseList) {
                        if (house.getFloorId().equals(floor.getId())) {
                            //若房屋属于该楼层，新建房屋vo，设置id和name，children为空
                            HouseTreeVO houseVO = new HouseTreeVO();
                            houseVO.setValue(house.getId());
                            houseVO.setLabel(house.getId() + "号");
                            houseVO.setChildren(null);
                            houseListVO.add(houseVO);
                        }
                    }
                    floorVO.setChildren(houseListVO);
                    floorListVO.add(floorVO);
                }
            }
            buildingVO.setChildren(floorListVO);
            res.add(buildingVO);
        }
        return res;
    }

    //根据房屋id获取房屋位置
    @Override
    public String getHouseNameById(Integer id) {
        HouseEntity house = baseMapper.selectById(id);
        if(house.getAddress()!=null){
            return house.getAddress();
        }
        FloorEntity floor = floorDao.selectById(house.getFloorId());
        BuildingEntity building = buildingDao.selectById(house.getBuildingId());
        String name=building.getName() + floor.getFloorNumber()+"层" + house.getId() + "号";
        house.setAddress(name);
        baseMapper.updateById(house);
        return name;
    }

    //计算房屋分数
    @Override
    public double calculateHousePoint(Integer houseId) {
        HouseEntity house = baseMapper.selectById(houseId);
        double totalPoint =0;
        if(house.getFireExtinguisherStatus()!=null){
            totalPoint+=house.getFireExtinguisherStatus();
        }
        if(house.getSmokeDetectorStatus()!=null){
            totalPoint+=house.getSmokeDetectorStatus();
        }
        if(house.getPassageUnblockStatus()!=null){
            totalPoint+=house.getPassageUnblockStatus();
        }
        if(house.getGasStatus()!=null){
            totalPoint+=house.getGasStatus();
        }
        if(house.getElectricity()!=null){
            totalPoint+=house.getElectricity();
        }
        totalPoint=totalPoint/18*100;
        return totalPoint;
    }

    //获取业主分数
    @Override
    public R getOwnerPoint(Integer ownerId) {
        HouseEntity house = baseMapper.selectOne(new LambdaQueryWrapper<HouseEntity>().eq(HouseEntity::getOwnerId, ownerId));
        if(house==null){
            return R.error("未找到该业主的房屋信息");
        }
        //总分
        double totalPoint=this.calculateHousePoint(house.getId());
        //占比
        List<String> proportion=new ArrayList<>();
        proportion.add(String.format("%.2f",4.0/18*100)+"%");
        proportion.add(String.format("%.2f",3.0/18*100)+"%");
        proportion.add(String.format("%.2f",3.0/18*100)+"%");
        proportion.add(String.format("%.2f",3.0/18*100)+"%");
        proportion.add(String.format("%.2f",5.0/18*100)+"%");
        //每项分数
        List<String> pointList = new ArrayList<>();
        pointList.add(String.format("%.2f",house.getFireExtinguisherStatus()/4.0*100));
        pointList.add(String.format("%.2f",house.getSmokeDetectorStatus()/3.0*100));
        pointList.add(String.format("%.2f",house.getPassageUnblockStatus()/3.0*100));
        pointList.add(String.format("%.2f",house.getGasStatus()/3.0*100));
        pointList.add(String.format("%.2f",house.getElectricity()/5.0*100));
        return R.ok().put("totalPoint",String.format("%.2f",totalPoint))
                .put("pointList",pointList)
                .put("proportion",proportion);
    }

    //获取房屋基本信息
    @Override
    public HouseBasicInfoVO getBasicInfo(Integer ownerId) {
        OwnerEntity owner = ownerService.getById(ownerId);
        Integer houseId = owner.getHouseId();
        HouseEntity house = this.getById(houseId);
        InspectorEntity inspector = inspectorDao.selectById(house.getSafetyInspectorId());
        InspectionEntity inspection = inspectionDao.selectLastInspectionByHouseId(houseId);

        HouseBasicInfoVO vo=new HouseBasicInfoVO();
        vo.setOwnerName(owner.getName());
        vo.setHouseId(houseId);
        vo.setInspectorName(inspector.getName());
        vo.setInspectorPhone(inspector.getPhone());
        vo.setLastInspectionDate(inspection.getInspectionDate());
        vo.setLastInspectionResult(inspection.getResult());
        vo.setHasDiagram(StrUtil.isNotBlank(house.getEvacuationMap()));
        vo.setAddress(house.getAddress());
        return vo;
    }

    //房屋统计信息
    @Override
    public HouseStatisticsVO getSafeStatistics(Integer ownerId) {
        OwnerEntity owner = ownerService.getById(ownerId);
        HouseEntity house=this.getById(owner.getHouseId());
        InspectionEntity lastInspection=inspectionDao.selectLastInspectionByHouseId(owner.getHouseId());

        //获取各种状态
        List<Boolean> extinguisherStatus=new ArrayList<>();
        extinguisherStatus.add(lastInspection.getExtinguisherLeadSealing());
        extinguisherStatus.add(lastInspection.getExtinguisherPressure());
        extinguisherStatus.add(lastInspection.getExtinguisherDamaged());
        extinguisherStatus.add(lastInspection.getExtinguisherExpired());

        List<Boolean> smokeDetectorStatus=new ArrayList<>();
        smokeDetectorStatus.add(lastInspection.getDetectorElectricity());
        smokeDetectorStatus.add(lastInspection.getDetectorSelfTest());
        smokeDetectorStatus.add(lastInspection.getDetectorNoError());

        List<Boolean> gasStatus=new ArrayList<>();
        gasStatus.add(lastInspection.getGasNoLeakage());
        gasStatus.add(lastInspection.getGasMeterStatus());
        gasStatus.add(lastInspection.getGasAutomaticShutOff());

        List<Boolean> powerStatus=new ArrayList<>();
        powerStatus.add(lastInspection.getCircuitStatus());
        powerStatus.add(lastInspection.getElectricalInsulation());
        powerStatus.add(lastInspection.getStandbyPower());
        powerStatus.add(lastInspection.getElectricalLoad());
        powerStatus.add(lastInspection.getElectricalGrounding());

        //查询近七次的检查日期和分数，需要倒序
        List<Date> dates = inspectionService.get7Dates(owner.getHouseId());
        Collections.reverse(dates);
        List<Double> points = inspectionService.get7Points(owner.getHouseId());
        Collections.reverse(points);

        //组装vo
        HouseStatisticsVO vo=new HouseStatisticsVO();
        vo.setInspectionId(lastInspection.getId());
        vo.setHouseLocation(this.getHouseNameById(owner.getHouseId()));
        vo.setTotalPoint(lastInspection.getResult());
        vo.setInspectionCount(inspectionService.getHouseCountThisMonth(owner.getHouseId()));
        vo.setLastInspectionDate(lastInspection.getInspectionDate());
        vo.setDateList(dates);
        vo.setPointList(points);
        vo.setUnblockPercent(house.getPassageUnblockStatus()/3.0*100);
        vo.setExtinguisherStatus(extinguisherStatus);
        vo.setSmokeDetectorStatus(smokeDetectorStatus);
        vo.setGasStatus(gasStatus);
        vo.setPowerStatus(powerStatus);
        vo.setEvacuationMap(house.getEvacuationMap());
        vo.setSummary(lastInspection.getSummary());
        vo.setAiSuggestion(lastInspection.getAiSuggestion());
        return vo;
    }

    @Override
    public Integer getHouseNumByBuildingId(Integer buildingId) {
        LambdaQueryWrapper<HouseEntity> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(HouseEntity::getBuildingId,buildingId);
        return Math.toIntExact(baseMapper.selectCount(wrapper));
    }

    @Override
    public IPage<ResponsibleForVO> getInspectorHouseList(Map<String, Object> params, Integer inspectorId) {
        InspectorEntity inspector = inspectorDao.selectById(inspectorId);
        //查询
        String key = (String) params.get("key");
        // 根据检查员负责的房屋号和输入的条件查询
        IPage<ResponsibleForVO> res = baseMapper.selectResponsibleForVOPage(new Query<ResponsibleForVO>().getPage(params), key, inspector.getBuildingId());
        //计算总分
        List<ResponsibleForVO> records = res.getRecords();
        for(ResponsibleForVO vo: records){
            vo.setScore(this.calculateHousePoint(vo.getId()));
        }
        res.setRecords(records);

        return res;
    }

    //按性别区分的分数
    @Override
    public List<List<Double>> getScoresBySex(Integer inspectorId) {
        //检查员负责的房屋
        LambdaQueryWrapper<HouseEntity> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(HouseEntity::getSafetyInspectorId,inspectorId);
        List<HouseEntity> houses = this.list(wrapper);

        List<List<Double>> scores = new ArrayList<>();
        List<Double> scoresA=new ArrayList<>();
        List<Double> scoresB=new ArrayList<>();
        for(HouseEntity house: houses){
            //得到业主
            OwnerEntity owner = ownerService.getById(house.getOwnerId());
            double score=this.calculateHousePoint(house.getId());
            if(owner.getSex().equals("男")){
                scoresA.add(score);
            }else{
                scoresB.add(score);
            }
        }
        scores.add(scoresA);
        scores.add(scoresB);
        return scores;
    }

    @Override
    public void setDeviceIdWithDevice(DeviceEntity device) {
        HouseEntity houseEntity = new HouseEntity();
        houseEntity.setId(device.getHouseId());
        if (DeviceTypeEnum.FIRE_EXTINGUISHER.getCode().equals(device.getType())) {
            houseEntity.setFireExtinguisherId(device.getId());
        } else if (DeviceTypeEnum.SMOKE_DETECTOR.getCode().equals(device.getType())) {
            houseEntity.setSmokeDetectorId(device.getId());
        } else {
            throw new RRException("设备类型不合法");
        }
        boolean success = this.updateById(houseEntity);
        if (!success) {
            throw new RRException("设置房屋对应设备id失败");
        }
    }

}
